#include "CameraProxy.h"
#include "LionMath.h"
#include "Components/LionRenderWindowComponent.h"

using namespace Lion;

CameraProxy::CameraProxy()
    : m_pCamera(nullptr)
    , m_eMoveDir(MOVE_NONE)
    , m_moveSpeed(20)
    , m_isCameraRotation(false)
    , m_pitch(0.0f)
    , m_yaw(0.0f)
{
}

void CameraProxy::setCamera(Lion::RenderWindowComponent* pCamera)
{
    m_pCamera = pCamera;

    m_eMoveDir = MOVE_NONE;
    m_moveSpeed = 20;
    m_isCameraRotation = false;
    m_pitch = 0.0f;
    m_yaw = 0.0f;
}

void CameraProxy::setPosition(const Vec3& pos)
{
    if(m_pCamera != nullptr)
        m_pCamera->setPosition(pos);
}

void CameraProxy::setDirection(const Vector3F32 &dir, const Vector3F32 &up)
{
    if (m_pCamera != nullptr)
        m_pCamera->setDirection(dir, up);
}

void CameraProxy::setAspect(f32 aspect)
{
    if (m_pCamera != nullptr)
        m_pCamera->setAspect(aspect);
}

void CameraProxy::update(f32 deltaTime)
{
    if (m_pCamera == nullptr)
        return;

    Vector3F32 vMoveDelta = Vector3F32::ZERO;
    if (m_eMoveDir & MOVE_FORWARD)
    {
        vMoveDelta -= m_pCamera->getDirection() * deltaTime * m_moveSpeed;
    }
    if (m_eMoveDir & MOVE_BACK)
    {
        vMoveDelta += m_pCamera->getDirection() * deltaTime * m_moveSpeed;
    }
    if (m_eMoveDir & MOVE_LIFT)
    {
        vMoveDelta -= m_pCamera->getRight() * deltaTime * m_moveSpeed;
    }
    if (m_eMoveDir & MOVE_RIGHT)
    {
        vMoveDelta += m_pCamera->getRight() * deltaTime * m_moveSpeed;
    }

    m_pCamera->setPosition(m_pCamera->getPosition() + Vec3(vMoveDelta));
}

void CameraProxy::moveBegin(E_MOVE_DIR dir)
{
    m_eMoveDir |= dir;
}

void CameraProxy::moveEnd(E_MOVE_DIR dir)
{
    m_eMoveDir &= ~dir;
}

void CameraProxy::rotateBegin()
{
    m_isCameraRotation = true;
}

void CameraProxy::rotateEnd()
{
    m_isCameraRotation = false;
}

void CameraProxy::rotate(const Radian& pitch, const Radian& yaw)
{
    if (m_isCameraRotation)
    {
         m_pitch += pitch;
         m_yaw += yaw;
        _rotate();
    }
}

void CameraProxy::_rotate()
{
    if (m_pCamera == nullptr)
        return;

    Matrix3F32 rot, rot_x, rot_y/*, rot_x_90*/;
    //rot_x_90.fromAngleAxisX(Util::HALF_PI);
    rot_x.fromAngleAxisX(m_pitch.valueRadians());
    rot_y.fromAngleAxisY(m_yaw.valueRadians());
    rot = rot_y * rot_x;
    m_pCamera->setOrientation(Quaternion(rot));
}
